package org.lemon.transport.rule.engine.mqtt.handler;

import io.netty.channel.Channel;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import io.netty.handler.codec.mqtt.*;
import io.netty.util.concurrent.Promise;
import lombok.extern.slf4j.Slf4j;
import org.lemon.transport.rule.engine.mqtt.MqttClientImpl;
import org.lemon.transport.rule.engine.mqtt.model.MqttConnectResult;

/**
 * mqtt channel 消息处理
 */
@Slf4j
public class MqttChannelHandler extends SimpleChannelInboundHandler<MqttMessage> {

    private final MqttClientImpl client;
    private final Promise<MqttConnectResult> connectFuture;

    public MqttChannelHandler(MqttClientImpl client, Promise<MqttConnectResult> connectFuture) {
        this.client = client;
        this.connectFuture = connectFuture;
    }

    @Override
    protected void channelRead0(ChannelHandlerContext ctx, MqttMessage msg) throws Exception {

        log.info("messageType: {}", msg.fixedHeader().messageType());
        switch (msg.fixedHeader().messageType()) {
            case CONNACK:
                handleConnAck(ctx.channel(), (MqttConnAckMessage) msg);
                break;
            default:
                break;
        }
    }

    private void handleConnAck(Channel channel, MqttConnAckMessage message) {

        MqttFixedHeader mqttFixedHeaderInfo = message.fixedHeader();
        MqttConnAckVariableHeader mqttConnectVariableHeaderInfo = message.variableHeader();

        //	构建返回报文， 可变报头
        MqttConnAckVariableHeader mqttConnAckVariableHeaderBack = new MqttConnAckVariableHeader(MqttConnectReturnCode.CONNECTION_ACCEPTED, false);
        //	构建返回报文， 固定报头
        MqttFixedHeader mqttFixedHeaderBack = new MqttFixedHeader(MqttMessageType.CONNACK, mqttFixedHeaderInfo.isDup(), MqttQoS.AT_MOST_ONCE, mqttFixedHeaderInfo.isRetain(), 0x02);
        //	构建CONNACK消息体
        MqttConnAckMessage connAck = new MqttConnAckMessage(mqttFixedHeaderBack, mqttConnAckVariableHeaderBack);
        log.info("back--" + connAck.toString());
        channel.writeAndFlush(connAck);
    }
}
